package com.mysns.web.controller;

import java.security.NoSuchAlgorithmException;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.mysterylab.utopiaframework.util.security.DigestUtil;
import org.mysterylab.utopiaframework.util.validator.RegExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.mysns.core.dao.GenericUserDao;
import com.mysns.core.domain.Individual;
import com.mysns.util.UrlParam;

/**
 * 用户的各种动作的控制器, 包括有:<br><ul>
 * <li>1) 注册, 登录, 注销</li></ul>
 * 
 * @author zhouych
 */
@Controller
@RequestMapping("/account")
public class AccountController {

	/**
	 * Logger
	 */
	private static Logger logger = LoggerFactory.getLogger(AccountController.class);
	
	/**
	 * 操作用户的 Dao
	 */
	@Resource
	private GenericUserDao genericUserDao;
	
	
	/**
	 * 进入登录页面.
	 * 
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String login() {
		return UrlParam.VIEW_LOGIN;
	}
	
	/**
	 * 验证用户登录的方法.
	 * 
	 * @param request
	 * @param response
	 * @param useraccount
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(HttpServletRequest request, HttpServletResponse response,
			@RequestParam(value = "username", required = true) String username,
			@RequestParam(value = "password", required = true) String password,
			ModelMap model) {
		
		return "redirect:/index";
	}
	
	/**
	 * 注销用户, 返回主页面.
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public String logout() {
		return "redirect:/index";
	}
	
	/**
	 * 进入注册页面.
	 * 
	 * @return
	 */
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	public String register() {
		return UrlParam.VIEW_REGISTER;
	}
	
	/**
	 * 用户注册.
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws NoSuchAlgorithmException 
	 */
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public String register(HttpServletRequest request, HttpServletResponse response,
			@RequestParam(value = "loginName", required = true) String loginName,
			@RequestParam(value = "email", required = true) String email,
			@RequestParam(value = "password1", required = true) String password1,
			@RequestParam(value = "password2", required = true) String password2,
			@RequestParam(value = "checkcode", required = true) String checkcode,
			ModelMap model) throws NoSuchAlgorithmException {
		
		String error = null;
		
		if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(email)
				|| StringUtils.isEmpty(password1) || StringUtils.isEmpty(password2)
				|| StringUtils.isEmpty(checkcode)) {
			
			return UrlParam.VIEW_REGISTER;
		}
		
		// 用户名的长度需要控制在 4~12 位之间
		if (loginName.trim().length() < 4 || loginName.trim().length() > 12) {
			error = "用户名不符合要求";
			model.addAttribute("nameErr", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		// 用户的邮件需要符合规则
//		if (!Pattern.compile(RegExpression.REG_EMAIL).matcher(email).find()) {
//			error = "电子邮件格式不正确";
//			model.addAttribute("emailErr", error);
//			return UrlParam.VIEW_REGISTER;
//		}
		
		// 密码长度不能超过 20 位
		if (password1.trim().length() > 20) {
			error = "密码不符合要求";
			model.addAttribute("pwd1Err", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		// 两次输入密码必须一致
		if (!password2.trim().equals(password1.trim())) {
			error = "两次输入密码必须一致";
			model.addAttribute("pwd2Err", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		// 正确的验证码
		String correctCode = (String) request.getSession().getAttribute(
				com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		
		// 验证验证码
		if (!checkcode.trim().equals(correctCode)) {
			error = "验证码不正确";
			model.addAttribute("codeErr", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		// 用户名已经被注册
		if (genericUserDao.findUniqueBy("loginName", loginName.trim()) != null) {
			error = "用户名已经被注册";
			model.addAttribute("nameRptErr", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		// 该邮箱已经被注册
		if (genericUserDao.findUniqueBy("email", email.trim()) != null) {
			error = "该邮箱已经被注册";
			model.addAttribute("emailRptErr", error);
			return UrlParam.VIEW_REGISTER;
		}
		
		/*
		 * 这里应该根据用户的类型而进行选择, 默认使用 Individual
		 */
		Individual newUser = new Individual();
		newUser.setLoginName(loginName);
		// 密码需要使用 Md5 进行加密
		newUser.setPassword(DigestUtil.getMD5String(password1));
		newUser.setEmail(email);
		// 处于邮箱未认证状态
		newUser.setStatus(1);
		// 将新用户保存到数据库中
		genericUserDao.save(newUser);
		
		/*
		 * 用户注册成功后, 应该发送链接邮件, 同时进入提示页面.
		 * 由于时间问题, 这里暂时不进行处理.
		 */
		logger.info("save new user to database.");
		
		return "redirect:/index";
	}
	
	/**
	 * 激活用户，有两种情况：<br><ul>
	 * <li>1) 刚注册完之后.</li>
	 * <li>2) 当注册完之后没有收到确认信.</li></ul>
	 * 
	 * @return
	 */
	@RequestMapping(value="/active")
	public String signupmail() {
		return null;
	}
	
	/**
	 * 验证邮箱, 邮箱认证的规则是:<br>
	 * http://www.mysns.com/acount/emailconfirm?email=enljODE1MTYwQDE2My5jb20<br>
	 * 其中"enljODE1MTYwQDE2My5jb20"是被 Base64 加密的字符串, 原型是: zyc815160@163.com<br>
	 * 邮箱验证失效的原因有:<br><ul>
	 * <li>1) 此Email地址已完成验证.</li>
	 * <li>2) 您已更换验证 Email 地址, 请以收到的最后一封验证邮件为准.</li>
	 * <li>3) 此验证邮件已过期, 重新发送验证邮件.</li></ul>
	 * 
	 * @return
	 */
	@RequestMapping(value = "/emailconfirm")
	public String activeEmail() {
		return null;
	}
	
	/**
	 * 找回密码, 往用户指定的邮箱里发送一条找回密码的链接, 规则如下:<br>
	 * http://www.mysns.com/account/getpassword?email=enljODE1MTYwQDE2My5jb20
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getpassword")
	public String getPassword() {
		return null;
	}
	
	/**
	 * 重设密码, 在这里用户需要输入新密码并确认新密码.
	 * 
	 * @return
	 */
	@RequestMapping(value = "/resetpassword")
	public String resetPassword() {
		return null;
	}
}
